<template>
    <div class="in-out-type-page">
        <!-- 搜索区域 -->
        <el-card class="search-card" shadow="never">
            <el-form :inline="true" :model="searchForm" label-width="auto" class="filter-form">
                <el-form-item label="类型">
                    <el-input v-model="searchForm.typeName" clearable placeholder="请输入类型名称/编号" style="width: 220px" />
                </el-form-item>
                <el-form-item label="状态">
                    <el-select v-model="searchForm.state" clearable placeholder="请选择" style="width: 180px">
                        <el-option label="启用" :value="1" />
                        <el-option label="停用" :value="0" />
                    </el-select>
                </el-form-item>
                <el-form-item label="方向">
                    <el-select v-model="searchForm.direction" clearable placeholder="请选择" style="width: 180px">
                        <el-option label="入库" :value="1" />
                        <el-option label="出库" :value="2" />
                    </el-select>
                </el-form-item>
                <el-form-item label="操作人">
                    <el-input v-model="searchForm.operator" clearable placeholder="请输入" style="width: 180px" />
                </el-form-item>
                <el-form-item>
                    <el-space>
                        <el-button @click="handleReset">重置</el-button>
                        <el-button type="primary" @click="handleQuery">
                            <el-icon>
                                <Search />
                            </el-icon>
                            查询
                        </el-button>
                    </el-space>
                </el-form-item>
            </el-form>
        </el-card>

        <!-- 操作按钮和表格 -->
        <el-card class="table-card" shadow="never">
            <div class="toolbar">
                <el-space wrap>
                    <el-button type="primary" @click="handleCreate">
                        <el-icon>
                            <Plus />
                        </el-icon>
                        新增
                    </el-button>
                    <el-button type="danger" @click="handleBatchDelete" :disabled="!multipleSelection.length">
                        <el-icon>
                            <Delete />
                        </el-icon>
                        删除
                    </el-button>
                    <el-button @click="handleExport">
                        <el-icon>
                            <Download />
                        </el-icon>
                        导出
                    </el-button>
                </el-space>
            </div>

            <el-table ref="tableRef" v-loading="loading" :data="tableData" border style="width: 100%"
                @selection-change="handleSelectionChange">
                <el-table-column type="selection" width="55" />
                <el-table-column type="index" label="序号" width="60" :index="getIndex" />
                <el-table-column prop="typeCode" label="类型编号" min-width="140" show-overflow-tooltip />
                <el-table-column prop="typeName" label="类型名称" min-width="160" show-overflow-tooltip />
                <el-table-column prop="direction" label="方向" width="100" align="center">
                    <template #default="{ row }">
                        <el-tag v-if="row.direction === 1 || row.direction === '入库'" type="success">入库</el-tag>
                        <el-tag v-else-if="row.direction === 2 || row.direction === '出库'" type="primary">出库</el-tag>
                        <span v-else>{{ row.direction || '-' }}</span>
                    </template>
                </el-table-column>
                <el-table-column prop="sortOrder" label="排序" width="80" align="center" />
                <el-table-column prop="state" label="状态" width="100" align="center">
                    <template #default="{ row }">
                        <el-tag v-if="row.state === 1" type="success">启用</el-tag>
                        <el-tag v-else type="danger">停用</el-tag>
                    </template>
                </el-table-column>
                <el-table-column prop="remark" label="备注" min-width="300" show-overflow-tooltip />
                <el-table-column prop="operator" label="操作人" width="120" show-overflow-tooltip />
                <el-table-column prop="operationTime" label="操作时间" width="180" align="center">
                    <template #default="{ row }">
                        {{ formatDateTime(row.operationTime || row.createTime || row.updateTime) }}
                    </template>
                </el-table-column>
                <el-table-column label="操作" fixed="right" width="160" align="center">
                    <template #default="{ row }">
                        <el-button link type="primary" size="small" @click="handleEdit(row)">
                            编辑
                        </el-button>
                        <el-button link type="danger" size="small" @click="handleDelete(row)">
                            删除
                        </el-button>
                    </template>
                </el-table-column>
            </el-table>

            <!-- 分页 -->
            <div class="pagination-wrapper">
                <el-pagination v-model:current-page="page.pageindex" v-model:page-size="page.pagesize"
                    :page-sizes="[10, 20, 30, 50]" :total="page.listCount"
                    layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
                    @current-change="handlePageChange" />
            </div>
        </el-card>

        <!-- 新增/编辑对话框 -->
        <el-dialog v-model="dialogVisible" :title="isEdit ? '编辑出入库类型' : '新增出入库类型'" width="600px"
            @close="handleDialogClose">
            <el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
                <el-form-item label="类型编号" prop="typeCode">
                    <el-input v-model="form.typeCode" placeholder="点击自动生成按钮获取编号" readonly class="form-input">
                        <template #append>
                            <el-button @click="generateTypeCode" :loading="generatingCode" :disabled="isEdit">
                                自动生成
                            </el-button>
                        </template>
                    </el-input>
                </el-form-item>
                <el-form-item label="类型名称" prop="typeName">
                    <el-input v-model="form.typeName" placeholder="请输入类型名称" />
                </el-form-item>
                <el-form-item label="方向" prop="direction">
                    <el-radio-group v-model="form.direction">
                        <el-radio :label="1">入库</el-radio>
                        <el-radio :label="2">出库</el-radio>
                    </el-radio-group>
                </el-form-item>
                <el-form-item label="排序" prop="sortOrder">
                    <el-input-number v-model="form.sortOrder" :min="0" :max="9999" placeholder="请输入排序" />
                </el-form-item>
                <el-form-item label="状态" prop="state">
                    <el-radio-group v-model="form.state">
                        <el-radio :label="1">启用</el-radio>
                        <el-radio :label="0">停用</el-radio>
                    </el-radio-group>
                </el-form-item>
                <el-form-item label="备注">
                    <el-input v-model="form.remark" type="textarea" :rows="4" placeholder="请输入备注" />
                </el-form-item>
            </el-form>
            <template #footer>
                <div style="text-align: right;">
                    <el-button @click="dialogVisible = false">取消</el-button>
                    <el-button type="primary" @click="handleSave" :loading="saving">
                        确定
                    </el-button>
                </div>
            </template>
        </el-dialog>
    </div>
</template>

<script lang="ts" setup>
import { onMounted, reactive, ref } from 'vue'
import { ElMessage, ElMessageBox, type TableInstance, type FormInstance, type FormRules } from 'element-plus'
import { Search, Plus, Delete, Download } from '@element-plus/icons-vue'
import myaxios from '@/http/MyAxios'
import moment from 'moment'

// 搜索表单
const searchForm = reactive({
    typeName: '',
    state: null as number | null,
    direction: null as number | null,
    operator: ''
})

// 分页信息
const page = reactive({
    pageindex: 1,
    pagesize: 10,
    listCount: 0
})

// 表格数据
const tableData = ref<any[]>([])
const loading = ref(false)
const multipleSelection = ref<any[]>([])
const tableRef = ref<TableInstance>()

// 对话框相关
const dialogVisible = ref(false)
const isEdit = ref(false)
const formRef = ref<FormInstance>()
const saving = ref(false)
const generatingCode = ref(false)

// 表单数据
const form = reactive({
    outTypeId: null as number | null,
    typeCode: '',
    typeName: '',
    direction: 1, // 1: 入库, 2: 出库
    sortOrder: 0,
    state: 1, // 1: 启用, 0: 停用
    remark: ''
})

// 表单验证规则
const rules: FormRules = {
    typeCode: [
        {
            required: true,
            message: '请输入类型编号',
            trigger: 'blur',
            validator: (rule: any, value: any, callback: any) => {
                if (!value || (typeof value === 'string' && !value.trim())) {
                    callback(new Error('请输入类型编号'))
                } else {
                    callback()
                }
            }
        }
    ],
    typeName: [
        {
            required: true,
            message: '类型名称不能为空',
            trigger: 'blur',
            validator: (rule: any, value: any, callback: any) => {
                if (!value || (typeof value === 'string' && !value.trim())) {
                    callback(new Error('类型名称不能为空'))
                } else {
                    callback()
                }
            }
        }
    ],
    direction: [
        { required: true, message: '请选择方向', trigger: 'change' }
    ],
    sortOrder: [
        { required: true, message: '请输入排序', trigger: 'blur' }
    ],
    state: [
        { required: true, message: '请选择状态', trigger: 'change' }
    ]
}

// 将后端返回的数据标准化为前端统一字段
const normalizeOutTypeRecord = (item: any = {}) => {
    const directionRaw = item.direction ?? item.outTypeDirection ?? item.warehouDirection ?? item.warehouDirectionName
    let direction = 1
    if (typeof directionRaw === 'string') {
        if (directionRaw.includes('出')) direction = 2
        else direction = 1
    } else if (directionRaw !== undefined && directionRaw !== null) {
        direction = Number(directionRaw) === 2 ? 2 : 1
    }

    const stateRaw = item.state ?? item.outTypeState ?? item.warehouState ?? item.warehouStateName ?? item.warehouStart
    let state = 0
    if (typeof stateRaw === 'string') {
        state = stateRaw.includes('启') ? 1 : 0
    } else if (stateRaw !== undefined && stateRaw !== null) {
        state = Number(stateRaw) === 1 ? 1 : 0
    }

    return {
        outTypeId: item.outTypeId ?? item.warehouTypeId ?? item.id ?? item.warehouseTypeId ?? null,
        typeCode: item.typeCode ?? item.outTypeCode ?? item.warehouCode ?? item.warehouseCode ?? '',
        typeName: item.typeName ?? item.outTypeName ?? item.warehouName ?? item.warehouseName ?? '',
        direction,
        sortOrder: item.sortOrder ?? item.outTypeSort ?? item.warehouSort ?? 0,
        state,
        remark: item.remark ?? item.outTypeRemark ?? item.outTypeHome ?? item.warehouHome ?? item.warehouRemark ?? item.warehouseRemark ?? '',
        operator: item.operator ?? item.createor ?? item.creator ?? item.createUserName ?? '',
        operationTime: item.operationTime ?? item.updateTime ?? item.createTime ?? item.createDateTime ?? null
    }
}

const resolveOutTypeId = (row: any) => {
    const id = row?.outTypeId ?? row?.warehouTypeId ?? row?.id ?? row?.warehouseTypeId
    return id !== undefined && id !== null ? Number(id) : null
}

// 计算序号
const getIndex = (index: number) => {
    return (page.pageindex - 1) * page.pagesize + index + 1
}

// 加载数据
const loadData = async () => {
    loading.value = true
    try {
        const params: any = {
            pageindex: page.pageindex,
            pagesize: page.pagesize
        }

        // 添加搜索条件
        if (searchForm.typeName) {
            params.typeName = searchForm.typeName
        }
        if (searchForm.state !== null) {
            params.state = searchForm.state
        }
        if (searchForm.direction !== null) {
            params.direction = searchForm.direction
        }
        if (searchForm.operator) {
            params.operator = searchForm.operator
        }

        const res = await myaxios.get('/api/OutType/GetOutTypePage', { params })

        if (res.data && res.data.code === 200) {
            const result = res.data.data || {}
            const pages = result.pages || {}

            const rawList = pages.data || result.data || []
            tableData.value = Array.isArray(rawList) ? rawList.map(normalizeOutTypeRecord) : []
            page.listCount = Number(pages.listCount || result.listCount || 0)
        } else {
            ElMessage.error(res.data?.message || '查询失败')
            tableData.value = []
            page.listCount = 0
        }
    } catch (error: any) {
        console.error('查询失败:', error)
        ElMessage.error('查询失败，请稍后重试')
        tableData.value = []
        page.listCount = 0
    } finally {
        loading.value = false
    }
}

// 查询
const handleQuery = () => {
    page.pageindex = 1
    loadData()
}

// 重置
const handleReset = () => {
    searchForm.typeName = ''
    searchForm.state = null
    searchForm.direction = null
    searchForm.operator = ''
    page.pageindex = 1
    loadData()
}

// 新增
const handleCreate = () => {
    isEdit.value = false
    resetForm()
    dialogVisible.value = true
}

// 编辑
const handleEdit = (row: any) => {
    isEdit.value = true
    form.outTypeId = row.outTypeId || row.id
    form.typeCode = row.typeCode || ''
    form.typeName = row.typeName || ''
    form.direction = row.direction === '入库' ? 1 : (row.direction === '出库' ? 2 : (row.direction || 1))
    form.sortOrder = row.sortOrder || 0
    form.state = row.state !== undefined ? row.state : 1
    form.remark = row.remark || ''
    dialogVisible.value = true
}

// 删除
const handleDelete = async (row: any) => {
    try {
        await ElMessageBox.confirm('确认删除该出入库类型吗？', '警告', {
            type: 'warning',
            confirmButtonText: '确定',
            cancelButtonText: '取消'
        })

        const targetId = resolveOutTypeId(row)
        if (targetId === null || Number.isNaN(targetId)) {
            ElMessage.error('缺少出入库类型ID，无法删除')
            return
        }

        const res = await myaxios.delete('/api/OutType/DeleteOutType', {
            params: { outTypeId: targetId, warehouTypeId: targetId },
            data: { outTypeId: targetId }
        })

        if (res.data && res.data.code === 200) {
            ElMessage.success('删除成功')
            loadData()
        } else {
            ElMessage.error(res.data?.message || '删除失败')
        }
    } catch (error: any) {
        if (error !== 'cancel') {
            console.error('删除失败:', error)
            ElMessage.error('删除失败，请稍后重试')
        }
    }
}

// 批量删除
const handleBatchDelete = async () => {
    if (multipleSelection.value.length === 0) {
        ElMessage.warning('请选择要删除的数据')
        return
    }

    try {
        await ElMessageBox.confirm(
            `确认删除选中的 ${multipleSelection.value.length} 条数据吗？`,
            '警告',
            {
                type: 'warning',
                confirmButtonText: '确定',
                cancelButtonText: '取消'
            }
        )

        // 批量删除
        const deletePromises = multipleSelection.value.map((row: any) => {
            const targetId = resolveOutTypeId(row)
            if (targetId === null || Number.isNaN(targetId)) return Promise.resolve(null)
            return myaxios.delete('/api/OutType/DeleteOutType', {
                params: { outTypeId: targetId, warehouTypeId: targetId },
                data: { outTypeId: targetId }
            })
        })

        await Promise.all(deletePromises)
        ElMessage.success('批量删除成功')
        multipleSelection.value = []
        loadData()
    } catch (error: any) {
        if (error !== 'cancel') {
            console.error('批量删除失败:', error)
            ElMessage.error('批量删除失败，请稍后重试')
        }
    }
}

// 选择变化
const handleSelectionChange = (selection: any[]) => {
    multipleSelection.value = selection
}

// 保存
const handleSave = async () => {
    if (!formRef.value) return

    // 去除字符串字段的前后空白字符
    if (typeof form.typeCode === 'string') {
        form.typeCode = form.typeCode.trim()
    }
    if (typeof form.typeName === 'string') {
        form.typeName = form.typeName.trim()
    }
    if (typeof form.remark === 'string') {
        form.remark = form.remark.trim()
    }

    // 如果是新增且类型编号为空，自动生成
    if (!isEdit.value && !form.typeCode) {
        try {
            await generateTypeCode()
            if (!form.typeCode) {
                ElMessage.warning('请生成类型编号')
                return
            }
        } catch (error) {
            ElMessage.error('自动生成编号失败，请手动生成')
            return
        }
    }

    await formRef.value.validate(async (valid) => {
        if (valid) {
            saving.value = true
            try {
                // 构建请求数据
                const data: any = {
                    outTypeCode: form.typeCode,
                    outTypeName: form.typeName,
                    outTypeDirection: form.direction,
                    outTypeSort: form.sortOrder,
                    outTypeState: form.state,
                    outTypeHome: form.remark
                }

                // 编辑时才传递 outTypeId，且确保是数字类型
                if (isEdit.value && form.outTypeId) {
                    data.outTypeId = Number(form.outTypeId)
                }

                let res
                if (isEdit.value) {
                    res = await myaxios.put('/api/OutType/UpdateOutType', data)
                } else {
                    res = await myaxios.post('/api/OutType/CreateOutType', data)
                }

                if (res.data && res.data.code === 200) {
                    ElMessage.success(isEdit.value ? '更新成功' : '创建成功')
                    dialogVisible.value = false
                    loadData()
                } else {
                    ElMessage.error(res.data?.message || (isEdit.value ? '更新失败' : '创建失败'))
                }
            } catch (error: any) {
                console.error('保存失败:', error)
                ElMessage.error('保存失败，请稍后重试')
            } finally {
                saving.value = false
            }
        }
    })
}

// 时间片段顺序
const TIME_SEGMENT_ORDER = ['YYYY', 'YY', 'MM', 'DD', 'HH', 'MI', 'SS']

// 补零函数
const pad = (n: number, len = 2) => `${n}`.padStart(len, '0')

// 根据规则构建编号
const buildCodeFromRule = (rule: any) => {
    const now = new Date()
    const segments = (rule?.timeRule || '')
        .split(',')
        .map((s: string) => s.trim().toUpperCase())
        .filter(Boolean)
        .sort((a: string, b: string) => {
            const idxA = TIME_SEGMENT_ORDER.indexOf(a)
            const idxB = TIME_SEGMENT_ORDER.indexOf(b)
            if (idxA === -1 && idxB === -1) return 0
            if (idxA === -1) return 1
            if (idxB === -1) return -1
            return idxA - idxB
        })
    const timePart = segments
        .map((seg: string) => {
            switch (seg) {
                case 'YYYY': return String(now.getFullYear())
                case 'YY': return String(now.getFullYear()).slice(-2)
                case 'MM': return pad(now.getMonth() + 1)
                case 'DD': return pad(now.getDate())
                case 'HH': return pad(now.getHours())
                case 'MI': return pad(now.getMinutes())
                case 'SS': return pad(now.getSeconds())
                default: return ''
            }
        })
        .join('')
    const serialLength = Number(rule?.serialLength ?? 3)
    const serial = '1'.padStart(serialLength > 0 ? serialLength : 3, '0')
    return `${rule?.codePrefix || ''}${timePart}${serial}`
}

// 请求编号（优先使用GenerateNumber接口，失败则使用规则生成）
const requestNumber = async (targetCode: string, targetName: string) => {
    try {
        // 优先使用 GenerateNumber 接口
        const res = await myaxios.get('/api/Number/GenerateNumber', {
            params: { targetCode, targetName }
        })
        if (res?.data?.code === 200 && res?.data?.data) {
            return String(res.data.data)
        }
        throw new Error(res?.data?.message || '生成编号失败')
    } catch (err) {
        console.warn(`[numbering] GenerateNumber 接口不可用 (${targetCode})，尝试规则生成`, err)
        // 如果 GenerateNumber 接口不可用，则查询规则并生成
        const ruleRes = await myaxios.get('/api/Number/QueryNumberingRules', {
            params: { targetCode, targetName }
        })
        const list = Array.isArray(ruleRes?.data?.data) ? ruleRes.data.data : []
        if (list.length > 0) {
            return buildCodeFromRule(list[0])
        }
        throw new Error('未找到对应的编号规则，请先配置编号规则')
    }
}

// 生成类型编号
const generateTypeCode = async () => {
    generatingCode.value = true
    try {
        const code = await requestNumber('OutType', '出入库类型')
        form.typeCode = code
        ElMessage.success('编号生成成功')
    } catch (error: any) {
        console.error('生成编号失败:', error)
        ElMessage.error(error?.message || '生成编号失败，请先配置编号规则')
    } finally {
        generatingCode.value = false
    }
}

// 重置表单
const resetForm = () => {
    form.outTypeId = null
    form.typeCode = ''
    form.typeName = ''
    form.direction = 1
    form.sortOrder = 0
    form.state = 1
    form.remark = ''
    formRef.value?.clearValidate()
}

// 对话框关闭
const handleDialogClose = () => {
    resetForm()
}

// 分页大小变化
const handleSizeChange = () => {
    page.pageindex = 1
    loadData()
}

// 页码变化
const handlePageChange = () => {
    loadData()
}

// 导出
const handleExport = async () => {
    try {
        const params: any = {}
        if (searchForm.typeName) params.typeName = searchForm.typeName
        if (searchForm.state !== null) params.state = searchForm.state
        if (searchForm.direction !== null) params.direction = searchForm.direction
        if (searchForm.operator) params.operator = searchForm.operator

        const res = await myaxios.get('/api/OutType/ExportOutType', {
            params,
            responseType: 'blob'
        })

        const blob = new Blob([res.data], { type: 'application/vnd.ms-excel' })
        const url = URL.createObjectURL(blob)
        const a = document.createElement('a')
        a.href = url
        a.download = `出入库类型_${moment().format('YYYYMMDDHHmmss')}.xlsx`
        document.body.appendChild(a)
        a.click()
        document.body.removeChild(a)
        URL.revokeObjectURL(url)
        ElMessage.success('导出成功')
    } catch (error) {
        console.error('导出失败', error)
        ElMessage.error('导出失败，请稍后重试')
    }
}

// 格式化时间
const formatDateTime = (dateTime: string | Date | null | undefined) => {
    if (!dateTime) return '-'
    return moment(dateTime).format('YYYY-MM-DD HH:mm:ss')
}

// 初始化
onMounted(() => {
    loadData()
})
</script>

<style scoped>
.in-out-type-page {
    padding: 20px;
    background: #f5f7fa;
    min-height: 100vh;
}

.search-card {
    margin-bottom: 16px;
}

.filter-form {
    margin-bottom: 0;
}

.table-card {
    border-radius: 12px;
}

.toolbar {
    margin-bottom: 16px;
}

.pagination-wrapper {
    display: flex;
    justify-content: flex-end;
    margin-top: 16px;
}

.form-input {
    width: 100%;
}
</style>
